﻿;var piceditor = (function() {
	var fileDivName = 'FileDiv';
	var editCanvas = null;
	var editContext = null;
	var picCanvas = document.createElement('canvas');
	var clipCanvas = document.createElement('canvas');
	var picScale = 1;
	var picRotateAngle = 0;
	var mouseStarted = false;
	var preXPos = 0;
	var preYPos = 0;
	var oldTwoTouchDis = 0;
	var oldTouchAngle = 0;
	var oldCenterX = 0;
	var oldCenterY = 0;
	var picPosX = 0;
	var picPosY = 0;
	var picWidth = 0;
	var picHeight = 0;
	
	var centerMaskImage = null;
	var centerMaskImageList = [];
	var frameMaskImage = new Image();
	var curSelectMaskIndex = 0;
	var maskAlpha = 122;
	var maskCanvas = null;
	var maskContext = null;
	
	var picAreaWidth = 0;
	var picAreaHeight = 0;
	
	var picClipLeft = 0;
	var picClipTop = 0;
	var picClipWidth = 0;
	var picClipHeight = 0;
	
	var clipAreaLengthWidthRatio = 1;
	var clipAreaSizeR = 0.8;
	var picLoading = false;
	
	//注册组件队列
	var currentName = '';
	var compList = {}
	
	function init() {
		createWindow();
		bindEvent();
	}

    var browser={
        versions:function() {
            var u=navigator.userAgent, app = navigator.appVersion;
            return {//移动终端浏览器版本信息
                trident: u.indexOf('Trident') > -1, //IE内核
                presto: u.indexOf('Presto') > -1, //opera内核
                webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
                gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
                mobile: !!u.match(/AppleWebKit.*Mobile.*/) || !!u.match(/AppleWebKit/), //是否为移动终端
                ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
                android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或者uc浏览器
                iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, //是否为iPhone或者QQHD浏览器
                iPad: u.indexOf('iPad') > -1, //是否iPad
                webApp: u.indexOf('Safari') == -1 //是否web应该程序，没有头部与底部
            };
        }(),
        language:(navigator.browserLanguage || navigator.language).toLowerCase()
    }

	function createWindow() {
		var fileDiv = document.createElement("div");
		document.body.appendChild(fileDiv);
		
		fileDiv.id = fileDivName;
		fileDiv.style.position = "absolute";
		
		fileDiv.style.left = '0';
		fileDiv.style.right = '0';
		fileDiv.style.top = '0';
		fileDiv.style.bottom = '0';
		fileDiv.style.zIndex = 99999;

		var postion = 'position: absolute; left: 0; top: 0; bottom: 0; right: 0;';
		var buttonStyle = 'position: absolute; width: 5rem; top: 0; color: #fff;font-size:0.64rem; background-color:#12a5f8;text-align:center;border-radius:4px;line-height:1.6rem;';
		
        fileDiv.innerHTML =
	        '<div style="'+ postion +'" id="PicArea" >' +
	        	'<canvas id="EditCanvas" style="'+ postion +';width:100%;height:100%;"></canvas>' +
	        '</div>' +
	        '<div style="position:absolute;left:0;width:100%;bottom:1rem; height: 2.5rem;">' +
	            '<a id="Cancel" style="' + buttonStyle + 'left: 2rem;">取消</a>' +
	            '<a id="Confirm" style="' + buttonStyle + 'right:2rem;">确定</a>' +
	        '</div>'+
	        '<div id="Cinput"><input type="file"></div>';
        
		//计算初始值
		editCanvas = document.getElementById('EditCanvas');
		editCanvas.width = editCanvas.clientWidth;
		editCanvas.height = editCanvas.clientHeight;
		editContext = editCanvas.getContext("2d");
		
		picAreaWidth = editCanvas.clientWidth;
		picAreaHeight = editCanvas.clientHeight;
		
		fileDiv.style.display = "none";
		
//		var maskCount = 1;
//      for(var i = 0; i < maskCount; ++i)
//      {
        centerMaskImageList[0] = new Image();
        centerMaskImageList[0].src="data:image/*;image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsAQMAAABDsxw2AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURQAAAKd6PdoAAAABdFJOUwBA5thmAAAAIklEQVRo3u3BMQEAAADCoPVPbQo/oAAAAAAAAAAAAAAAeBkttAAB/+kJawAAAABJRU5ErkJggg==";
//      }
		centerMaskImage = centerMaskImageList[curSelectMaskIndex];
		
		frameMaskImage.src = "";
		
		maskCanvas = document.createElement('canvas');
		maskContext = maskCanvas.getContext("2d");
		maskCanvas.width = editCanvas.width;
		maskCanvas.height = editCanvas.height;
	}
	
	function fitWindow(w, h){ //函数：获取尺寸
		picClipWidth = picAreaWidth * clipAreaSizeR;
		picClipLeft = (picAreaWidth - picClipWidth) / 2;
		picClipHeight = picClipWidth*h/w;
		//picClipHeight = picClipWidth * clipAreaLengthWidthRatio;
		picClipTop = (picAreaHeight - picClipHeight) / 2;
		
		if (picClipTop < 0) {
			picClipTop = 0;
			picClipHeight = picAreaHeight;
		}
	}
	
	function bindEvent() {
		var hastouch = "ontouchstart" in window?true:false;
		var touchstart = 'touchstart';
		if (hastouch) {
			document.addEventListener('touchstart', onTouchStart, false);
			document.addEventListener('touchmove', onTouchMove, false);
			document.addEventListener('touchend', onTouchEnd, false);
		}
		else {
			editCanvas.addEventListener('mousedown', doMouseDown, true);
			editCanvas.addEventListener('mousemove', doMouseMove, false);
			editCanvas.addEventListener('mouseup', doMouseUp, false);
			editCanvas.addEventListener('mousewheel', doMouseWheel, false);
			touchstart = 'click';
		}
        document.getElementById('Confirm').addEventListener(touchstart, onClickConfirm, false);
        document.getElementById('Cancel').addEventListener(touchstart, onClickCancel, false);
        document.getElementById('Cinput').addEventListener('change', onFileSelected, false);
	}
	
	function updatePicSize() {
		var maxPicSize = 2000;
		if (picWidth > maxPicSize && picWidth > picHeight) {
			picHeight = picHeight * maxPicSize / picWidth;
			picWidth = maxPicSize;
		}
		else if (picHeight > maxPicSize && picWidth < picHeight) {
			picWidth = picWidth * maxPicSize / picHeight;
			picHeight = maxPicSize;
		}
	}
	
	function onFileSelected(event) {
		var oFile = event.target.files[0];
		if(!oFile){return false;}

		picLoading = true;
		var oReader = new FileReader();
		oReader.onload = function (e) {
			var picImage = new Image();
			picImage.onload = function () {
				picWidth = picImage.width;
				picHeight = picImage.height;
				
				updatePicSize();
				
				picCanvas.width = picWidth;
				picCanvas.height = picHeight;
				
				var drawContext = picCanvas.getContext('2d');
				
				// search image edge pixel position in case it is squashed vertically. begin
				drawContext.drawImage(picImage, 0, 0, 1, picImage.height, 0, 0, 1, picHeight);
				var data = drawContext.getImageData(0, 0, 1, picHeight).data;
				
				var ratio = 1;
				for (var checkPos = picHeight - 1;checkPos >= 0;checkPos--) {
					var alpha = data[(checkPos) * 4 + 3];
					if (alpha != 0) {
						ratio = (checkPos + 1) / picHeight;
						break;
					}
				}
				// end
				drawContext.drawImage(picImage, 0, 0, picImage.width, picImage.height, 0, 0, picWidth, picHeight / ratio);
				
				fitWindow(compList[currentName].w, compList[currentName].h);
				
				picPosX = 0;
				picPosY = 0;
				picScale = 1;
				picRotateAngle = 0;

				picLoading = false;
				maskAlpha = 122;
				updateMask(maskAlpha);
				drawImage();
				
				var fileDiv = document.getElementById(fileDivName);
				fileDiv.style.display = "block";
				document.getElementById('Cinput').innerHTML = '<input type="file"/>';
			};
			picImage.src = "data:image/*;" + e.target.result.substr(5, e.target.result.length - 5);
		};
		oReader.readAsDataURL(oFile);
	}
	
	function onClickCancel() {
		document.getElementById(fileDivName).style.display = "none";
	}
	
	function drawImage() {
		if (picLoading === true) {
			return;
		}
		
		editContext.clearRect(0, 0, editCanvas.width, editCanvas.height);
		// draw pic
		editContext.save();
		editContext.translate(picPosX, picPosY);
		editContext.rotate(picRotateAngle);

		editContext.drawImage(picCanvas, 0, 0, picWidth * picScale, picHeight * picScale);
		editContext.restore();
		
		// draw mask
		editContext.drawImage(maskCanvas, 0, 0, editCanvas.width, editCanvas.height);
	}
	
	function updateMask(alpha) {
		maskCanvas.width = editCanvas.width;
		maskCanvas.height = editCanvas.height;
		
		maskContext.clearRect(0, 0, maskCanvas.width, maskCanvas.height);
		maskContext.drawImage(centerMaskImage, picClipLeft, picClipTop, picClipWidth, picClipHeight);
		maskContext.drawImage(frameMaskImage, 0, 0, picClipLeft, picAreaHeight);
		maskContext.drawImage(frameMaskImage, picClipLeft + picClipWidth, 0, picClipLeft, picAreaHeight);
		maskContext.drawImage(frameMaskImage, picClipLeft, 0, picClipWidth, picClipTop);
		maskContext.drawImage(frameMaskImage, picClipLeft, picClipTop + picClipHeight, picClipWidth, picClipTop);
		
		var maskImageData = maskContext.getImageData(0, 0, maskCanvas.width, maskCanvas.height);
		for (var i = 0, n = maskImageData.data.length;i < n;i += 4) {
			if (maskImageData.data[i + 3] != 0) {
				maskImageData.data[i + 3] = alpha;
			}
		}
		maskContext.putImageData(maskImageData, 0, 0);
	}
	
	function getAngle(x1, y1, x2, y2) {
		return Math.atan2(y2 - y1, x2 - x1);
	}
	
	function onClickConfirm() {
		var clipContext = clipCanvas.getContext("2d");
		clipCanvas.width = compList[currentName].w;
		clipCanvas.height = compList[currentName].h;
		
		var scale = clipCanvas.width / picClipWidth;
		
		clipContext.save();
		clipContext.translate((picPosX - picClipLeft) * scale, (picPosY - picClipTop) * scale);
		clipContext.rotate(picRotateAngle);
		clipContext.drawImage(picCanvas, 0, 0, picWidth * picScale * scale, picHeight * picScale * scale);
		clipContext.restore();
		
		var imageData = clipContext.getImageData(0, 0, clipCanvas.width, clipCanvas.height);
		
		clipContext.clearRect(0, 0, clipCanvas.width, clipCanvas.height);
		
		clipContext.drawImage(centerMaskImage, 0, 0, clipCanvas.width, clipCanvas.height);
		var maskData = clipContext.getImageData(0, 0, clipCanvas.width, clipCanvas.height);
		
		for (var i = 0, n = maskData.data.length;i < n;i += 4) {
			if (maskData.data[i + 3] != 0) {
				imageData.data[i + 3] = 0;
			}
		}
		
		clipContext.putImageData(imageData, 0, 0);
		
		compList[currentName].callback(clipCanvas.toDataURL('image/png'), clipCanvas);
		
		document.getElementById(fileDivName).style.display = "none";
	}
	
	
	//----------------------------------PC--------------------------------------------------------------------//
	function doMouseDown(event) {
		if (event.target.id != "EditCanvas") {
			return;
		}
		mouseStarted = true;
		
		preXPos = event.pageX;
		preYPos = event.pageY;
		console.log(preXPos, preYPos)
	}
	
	function doMouseMove(event) {
		if (event.target.id != "EditCanvas") {
			return;
		}
		
		if (mouseStarted === false) {
			return;
		}
		
		if (isNaN(event.pageX) || isNaN(event.pageY)) {
			return;
		}
		
		picPosX += (event.pageX - preXPos);
		picPosY += (event.pageY - preYPos);
		preXPos = event.pageX;
		preYPos = event.pageY;
		
		drawImage();
	}
	
	function doMouseUp(event) {
		if (event.target.id != "EditCanvas") {
			return;
		}
		
		mouseStarted = false;
	}
	
	function doMouseWheel(event) {
		if (event.target.id != "EditCanvas") {
			return;
		}
		
		var oldScale = picScale;
		if (event.wheelDelta > 0) {
			picScale += 0.1;
		}
		else {
			picScale -= 0.1
		
		}
		
		if (picScale < 0.1) {
			picScale = 0.1;
		}
		
		var scaleRate = picScale / oldScale;
		picPosX = event.pageX - (event.pageX - picPosX) * scaleRate;
		picPosY = event.pageY - (event.pageY - picPosY) * scaleRate;
		
		drawImage();
	}
	
	//----------------------------------mobile--------------------------------------------------------------------//
	function onTouchStart(event) {
		if (event.target.id != "EditCanvas") {
			return;
		}
		
		event.preventDefault();
		mouseStarted = true;
		
		if (event.touches.length == 2) {
			if (isNaN(event.touches[0].pageX) || isNaN(event.touches[0].pageY) || isNaN(event.touches[1].pageX) || isNaN(event.touches[1].pageY)) {
				return;
			}
			
			oldTwoTouchDis = distance(event.touches[0].pageX, event.touches[0].pageY, event.touches[1].pageX, event.touches[1].pageY);
			oldCenterX = (event.touches[0].pageX + event.touches[1].pageX) / 2;
			oldCenterY = (event.touches[0].pageY + event.touches[1].pageY) / 2;
			oldTouchAngle = getAngle(event.touches[0].pageX, event.touches[0].pageY, event.touches[1].pageX, event.touches[1].pageY);
		}
		else if (event.touches.length == 1) {
			if (isNaN(event.touches[0].pageX) || isNaN(event.touches[0].pageY)) {
				return;
			}
			
			preXPos = event.touches[0].pageX;
			preYPos = event.touches[0].pageY;
		}
	}
	
	function onTouchMove(event) {
		if (event.target.id != "EditCanvas") {
			return;
		}
		
		if (mouseStarted === false) {
			return;
		}
		
		if (event.touches.length == 2) {
			if (isNaN(event.touches[0].pageX) || isNaN(event.touches[0].pageY) || isNaN(event.touches[1].pageX) || isNaN(event.touches[1].pageY)) {
				return;
			}
			
			// calc scale for this time
			var curTowTouchDis = distance(event.touches[0].pageX, event.touches[0].pageY, event.touches[1].pageX, event.touches[1].pageY);
			var scaleRate = curTowTouchDis / oldTwoTouchDis;
			picScale = picScale * scaleRate;
			oldTwoTouchDis = curTowTouchDis;
			
			// calc rotate angle
			var newCenterX = (event.touches[0].pageX + event.touches[1].pageX) / 2;
			var newCenterY = (event.touches[0].pageY + event.touches[1].pageY) / 2;
			
			var newAngle = getAngle(event.touches[0].pageX, event.touches[0].pageY, event.touches[1].pageX, event.touches[1].pageY);
			var offsetAngle = newAngle - oldTouchAngle;
			oldTouchAngle = newAngle;
			picRotateAngle = picRotateAngle + offsetAngle;
			
			// calc pic pos
			var oldDisPosToTouchCenter = distance(oldCenterX, oldCenterY, picPosX, picPosY);
			var newDisPosToTouchCenter = oldDisPosToTouchCenter * scaleRate;
			
			var oldAnglePosToTouchCenter = getAngle(oldCenterX, oldCenterY, picPosX, picPosY);
			var anglePosToTouchCenter = oldAnglePosToTouchCenter + offsetAngle;
			picPosX = newCenterX + Math.cos(anglePosToTouchCenter) * newDisPosToTouchCenter;
			picPosY = newCenterY + Math.sin(anglePosToTouchCenter) * newDisPosToTouchCenter;
			
			drawImage();
			
			oldCenterX = newCenterX;
			oldCenterY = newCenterY;
		}
		else if (event.touches.length = 1) {
			if (isNaN(event.touches[0].pageX) || isNaN(event.touches[0].pageY)) {
				return;
			}
			
			picPosX += (event.touches[0].pageX - preXPos);
			picPosY += (event.touches[0].pageY - preYPos);
			preXPos = event.touches[0].pageX;
			preYPos = event.touches[0].pageY;
			
			drawImage();
		}
	}
	
	function onTouchEnd(event) {
		if (event.target.id != "EditCanvas") {
			return;
		}
		
		if (event.touches.length == 0) {
			mouseStarted = false;
		}
		else if (event.touches.length == 1) {
			preXPos = event.touches[0].pageX;
			preYPos = event.touches[0].pageY;
		}
	}
	
	function distance(x1, y1, x2, y2) {
		return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
	}
	
	var uploadfn = function(id, options){
		currentName = id;
		compList[currentName] =	options;
		document.getElementById('Cinput').children[0].click();
	}
	init();
	return function(options){
		options.isBind ? document.getElementById(options.id).addEventListener('click', function(){
			uploadfn(options.id, options);
		}, false) : uploadfn('piceditor0618', options);
	};
})();